#include "Player.h"
#include "PlayerState.h"

Player::Player(sf::Vector2f Position /* = sf::Vector2f */) : Entity()
{
	Health = 100;
	vPosition = Position;
	sState = NULL;
	sName = "Player";
	curAnim = NULL;
	curSheet = NULL;
	bFlipped = false;
	bPlayerBody = NULL;
}


Player::~Player()
{
	for (unsigned int i = 0; i < vChildren.size(); i++)
	{
		delete vChildren[i];
	}

	if (curAnim)
	{
		delete curAnim;
	}
	if (curSheet)
	{
		delete curSheet;
	}
}

void Player::Init()
{
	//Box 2d objects, player position is parented to bPlayerDef
	b2BodyDef bPlayerDef;
	bPlayerDef.type = b2_dynamicBody;
	bPlayerDef.position.Set(vPosition.x,vPosition.y);

	bPlayerBody = bWorld->CreateBody(&bPlayerDef);
	bPlayerBody->SetFixedRotation(true);
	b2PolygonShape bPlayerShape;
	bPlayerShape.SetAsBox(48.0f,0.5);

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &bPlayerShape;
	fixtureDef.density = 0.3f;
	fixtureDef.friction = 0.1f;
	fixtureDef.restitution = 0.0f;

	bPlayerBody->CreateFixture(&fixtureDef);
	bPlayerBody->SetBullet(true);


	ChangeState(new PlayerJump());
}

void Player::Update()
{
	if (bEnabled == true)
	{
		sState->UpdateState(this);




		SetPosition(sf::Vector2f(bPlayerBody->GetPosition().x,bPlayerBody->GetPosition().y));
		curAnim->SetColor(cColor);
		curAnim->SetRotation(fRotation);
		curAnim->SetScale(fScale,fScale);
		curAnim->SetPosition(vPosition);
		curAnim->SetRotation(bPlayerBody->GetAngle());
		curAnim->Update();
		vVelocity = sf::Vector2f(bPlayerBody->GetLinearVelocity().x,bPlayerBody->GetLinearVelocity().y);
		//printf("%f %f\n",vPosition.x,vPosition.y);
	}
}

void Player::Draw()
{
	if (Renderer != NULL && bEnabled == true)
	{
		Renderer->Draw(*curAnim);
	}
}

void Player::ChangeState(PlayerState * state)
{
	if (sState != NULL)
	{
		sState->OnExit(this);
		delete sState;
	}
	sState = state;
	sState->OnEnter(this);
}

void Player::AnimSpeed(float fps)
{
	curAnim->SetLoopSpeed(fps);
}

void Player::ChangeAnim(std::string newAnim,float speed /* = 1.0f */)
{
	//Load the texture sheet
	curSheet =  mImageManager->Get("./data//Player//"+newAnim);
	//Load it as an animation.
	delete curAnim;
	curAnim = new AniSprite(*curSheet,curSheet->GetHeight(),curSheet->GetHeight());
	curAnim->SetLoopSpeed(speed);
	curAnim->SetOrigin(curSheet->GetHeight()/(float)2,(float)curSheet->GetHeight());

	//Maintains flipped-ness
	Flip(bFlipped);
	curAnim->Play();
}

void Player::Flip(bool flip /* = true */)
{
	bFlipped = flip;
	curAnim->FlipX(bFlipped);
}

void Player::ApplyForce(sf::Vector2f force)
{
	bPlayerBody->ApplyForce(b2Vec2(force.x,force.y),bPlayerBody->GetWorldPoint(b2Vec2(0,0)));
}

void Player::ApplyForceImpulse(sf::Vector2f force)
{
	bPlayerBody->ApplyLinearImpulse(b2Vec2(force.x,force.y),bPlayerBody->GetWorldPoint(b2Vec2(0,0)));
}

sf::Vector2f Player::GetVelocity()
{
	return sf::Vector2f(bPlayerBody->GetLinearVelocity().x,bPlayerBody->GetLinearVelocity().y);
}

bool Player::AniComplete()
{
	return curAnim->LoopComplete();
}